`include "macro.v"
module board_top (
    input  wire clk,
    input  wire rst,
    input  wire [23:0] device_switch,
    output wire [23:0] device_led,
    output wire [7:0] led_en,
    output wire led_ca,
	output wire led_cb,
    output wire led_cc,
	output wire led_cd,
	output wire led_ce,
	output wire led_cf,
	output wire led_cg,
	output wire led_dp
);
wire clk_cpu;
wire rst_n = ~rst;

reg [31:0] pc;
// NPC
wire [31:0] npc;
wire [31:0] pc_4;
// IROM
wire [31:0] inst;
// SEXT
wire [31:0] ext;
// RF
wire [31:0] rD1;
wire [31:0] rD2;
// ALU
wire [31:0] alu_c;
wire eq;
wire lt;
wire ltu;
// DRAM
wire [31:0] rd;
// control
wire [1:0] npc_op;
wire rf_we;
wire [2:0] sext_op;
wire [1:0] wd_sel;
wire alua_sel;
wire alub_sel;
wire [3:0] alu_op;
wire wen;
wire [1:0] sd_sel;
wire [2:0] ld_sel;
wire [31:0] device_digital;

always @(posedge clk_cpu or negedge rst_n) begin
    if (~rst_n) begin
        pc <= 'b0;
    end else begin
        pc <= npc;
    end
end

wire lock;
cpuclk u_cpuclk(
    .clk_in1(clk),
    .locked(lock),
    .clk_out1(clk_cpu)
);

IO_bridge u_IO_bridge(
    .clk(clk_cpu),
    .rst_n(rst_n),
    .addr(alu_c),
    .wdata(rD2),
    .wen(wen),
    .rdata(rd),
    .sd_sel(sd_sel),
    .ld_sel(ld_sel),
    .device_switch(device_switch),
    .device_led(device_led),
    // digital
    .led_en(led_en),
    .led_ca(led_ca),
    .led_cb(led_cb),
    .led_cc(led_cc),
    .led_cd(led_cd),
    .led_ce(led_ce),
    .led_cf(led_cf),
    .led_cg(led_cg),
    .led_dp(led_dp)
);

NPC u_npc(
    .clk(clk_cpu),
    .rst_n(rst_n),
    .npc_op(npc_op),
    .pc(pc),
    .alu_c(alu_c),
    .ext(ext),
    .npc(npc),
    .pc_4(pc_4)
);

// inst_mem imem(
prgrom u_prgrom(
    .a(pc[15:2]),
    .spo(inst)
);

SEXT u_sext(
    .sext_op(sext_op),
    .din(inst[31:7]),
    .ext(ext)
);

RF u_rf(
    .clk(clk_cpu),
    .rst_n(rst_n),
    .rf_we(rf_we),
    .rR1(inst[19:15]),
    .rR2(inst[24:20]),
    .wR(inst[11:7]),
    .rD1(rD1),
    .rD2(rD2),
    // wd_sel
    .wd_sel(wd_sel),
    .pc_4(pc_4),
    .alu_c(alu_c),
    .rd(rd),
    .ext(ext)
);

ALU u_alu(
    .alu_op(alu_op),
    .c(alu_c),
    .eq(eq),
    .lt(lt),
    .ltu(ltu),
    // alua_sel
    .alua_sel(alua_sel),
    .rD1(rD1),
    .pc(pc),
    // alub_sel
    .alub_sel(alub_sel),
    .rD2(rD2),
    .ext(ext)
);

control u_control(
    .opcode(inst[6:0]),
    .func7(inst[31:25]),
    .func3(inst[14:12]),
    .eq(eq),
    .lt(lt),
    .ltu(ltu),
    .npc_op(npc_op),
    .rf_we(rf_we),
    .sext_op(sext_op),
    .wd_sel(wd_sel),
    .alua_sel(alua_sel),
    .alub_sel(alub_sel),
    .alu_op(alu_op),
    .wen(wen),
    .sd_sel(sd_sel),
    .ld_sel(ld_sel)
);

endmodule